import _ from 'lodash';
import React from 'react';
import {Icon, Progress} from 'antd';
import utils from '../../../utils';
import classNames from 'classnames';
import Dropzone from 'react-dropzone';
import {ACCEPT_TYPE, IMG_PATH} from '../../../constants/form';
import './index.less';
import {WeaLocaleProvider} from "ecCom";
import fillin from "../../../apis/fillin";

const getLabel = WeaLocaleProvider.getLabel;

export default class FileUpload extends React.Component {
  static defaultProps = {
    tip: '',
    content: null,
    accept: '',
    maxNum: 5,
    maxSize: 20,
    fileType: 'UNLIMITED',
    customType: '',
    files: [],
    disableClick: false,
    onChange: () => { },
    onClick: () => { },
    onFileItemClick: null
  };

  state = {
    files: [],
    openId: null, // 选中打开的文件(进行重新选择操作时)
    multiple: true,
    uploading: false,
    uploadPercent: 0
  };

  componentWillMount() {
    const { files } = this.props;
    (files && files.length > 0) && (this.state.files = files);
  }

  componentWillReceiveProps(nextProps) {
    if('files' in nextProps && nextProps.files) {
      this.setState({ files: nextProps.files });
    }
  }

  addFile = acceptedFiles => {
    const { files, openId } = this.state;
    let newFiles = [];

    acceptedFiles = acceptedFiles.map(file => ({
      data: file,
      id: utils.UUID(),
      docid: -1,
      uploading: false,
      uploadPercent: 0,
      error: this.getError(file),
    }));

    // 进行重新选择操作
    if(openId) {
      const index = files.findIndex(file => openId === file.id);

      if(!acceptedFiles.length) return;

      files.splice(index, 1, ...acceptedFiles);
    } else {
      files.push(...acceptedFiles);
    }

    newFiles = [...files].slice(0, this.props.maxNum);

    this.setState({
      openId: null,
      multiple: true
    });
    this.onFilesChange([...newFiles]);
  }

  removeFile = (e, fileId) => {
    const { files } = this.state;
    const index = files.findIndex(file => fileId === file.id);

    files.splice(index, 1);
    this.onFilesChange([...files]);
    e.stopPropagation();
  }

  onFilesChange(files) {
    const that = this;
    const { accept, onUploading, modeId } = that.props;
    const _changeState = files => {
      this.setState({ files });
    };

    const _changeVal = files => {
      this.props.onChange(files);
    };

    files.forEach(file => {
      if(!file.error && file.docid === -1) {
        const fileType = file.data.type;
        file.uploading = true;
        file.uploadPercent = 5;
        _changeState(files);
        onUploading(true);
        if(fileType.toLowerCase().startsWith('image')) {
          const reader = new FileReader();
          reader.onload = function (e) { // 图片base64
            file.img = e.target.result;
          };
          reader.readAsDataURL(file.data);
        }

        let formData = new FormData();
        formData.append("modeId", modeId);
        formData.append("file", file.data);
        formData.append("fileType", fileType);

        file.uploadPercent = 20;
        _changeState(files);

        fillin.uploadFile(formData).then((res) => {
          if(res.docid) {
            file.docid = res.docid;

            setTimeout(function () {
              file.uploadPercent = 100;
              _changeState(files);

            }, 500);
            setTimeout(function () {
              file.uploading = false;
              _changeState(files);
              _changeVal(files);
              onUploading(false);

            }, 800);

          }
        }).catch((e) => {
          onUploading(false);
          console.log(e);
        });

        setTimeout(function () {
          file.uploadPercent = 50;
          _changeState(files);
        }, 500);
      }
    });

    _changeState(files);
    _changeVal(files);
  }

  onFileItemClick(fileId) {
    const { onFileItemClick } = this.props;

    if(_.isFunction(onFileItemClick)) {
      onFileItemClick(fileId);
    } else {
      this.openFileDialog(fileId);
    }
  }

  openFileDialog = fileId => {
    this.setState({
      openId: fileId,
      multiple: false
    });
    setTimeout(() => {
      this.dropzone.open();
    });
  }

  onCancel = () => {
    this.setState({
      openId: null,
      multiple: true
    });
  }

  getSize(size, hasSpace) {
    const units = ['KB', 'MB'];
    let unit = units[0];
    let i = 0;

    do {
      size = Math.ceil(size / 1024 * 10) / 10;
      unit = units[i++];
    } while(size >= 1024)

    return `${size}${hasSpace ? ' ' : ''}${unit}`;
  }

  getError(file) {
    const { maxSize, fileType, customType } = this.props;
    const matchs = file.name.match(/\.([^\.]+)$/);
    const unSupported = ['ext', 'bat', 'html', 'htm', 'shtml', 'shtm', 'js', 'css'];
    const type = matchs && matchs[1].toLowerCase();

    const acceptFileTypes = (!fileType || fileType == "UNLIMITED") ? null : (fileType === "CUSTOM" ? (customType && customType.split(",") || null) : ACCEPT_TYPE[fileType].split("、"));


    if(file.name.indexOf('.') === 0) {
      return getLabel('502254', '禁止上传系统文件');
    }

    if(unSupported.includes(type)) {
      return getLabel('502255', '不支持上传EXE、BAT、HTML、HTM、SHTML、SHTM、JS、CSS格式的文件。');
    }

    if(acceptFileTypes && acceptFileTypes.length > 0 && !acceptFileTypes.includes(type)) {
      return getLabel('506498', '仅支持文件格式') + " " + acceptFileTypes.join('、');
    }

    if(file.size > maxSize) {
      return `${getLabel('502256', '文件超过了') + this.getSize(maxSize)}`;
    }

    return '';
  }

  render() {
    const {
      maxNum, maxSize, tip, accept, content, disableClick, className, fileType, customType,
      onClick
    } = this.props;

    const { files, multiple } = this.state;

    const acceptTip = (!fileType || fileType == "UNLIMITED") ? "" : (fileType === "CUSTOM" ? customType : ACCEPT_TYPE[fileType]);

    const emptyImg = "";
    return (
      <div className={`wea-edc-upload-container ${className}`}>
        {files.map(({ data, id, error, img, uploading, uploadPercent }) => (
          <div className={'wea-edc-upload-inner'}>
            {
              uploading ?
                <Progress ecId={`${this && this.props && this.props.ecId || ''}_Progress@wsmp47@${id}`} percent={uploadPercent} strokeWidth={150} status="active" showInfo={false} />
                : null
            }
            <div className='clearfix wea-edc-upload-item' onClick={() => this.onFileItemClick(id)}>
              <div className='wea-edc-upload-file-img'><img src={img || (accept ? emptyImg : `${IMG_PATH}/attachment-file.png`)} /></div>
              <div className={classNames('wea-edc-upload-title', { 'has-error': !!error })}>
                {!data ? null : `${data.name} ${error ? '' : `(${!isNaN(data.size) ? this.getSize(data.size, true) : data.size})`}`}
                {!error ? null : <div>{`(${error})`}</div>}
              </div>
              <div className='wea-edc-upload-acts'>
                <i className='icon-edc-app-close-fill' onClick={e => this.removeFile(e, id)} />
              </div>
            </div>
          </div>
        ))}
        <Dropzone ecId={`${this && this.props && this.props.ecId || ''}_Dropzone@ok2b3j`}
          accept={accept}
          multiple={multiple}
          disableClick={disableClick}
          onClick={onClick}
          onDrop={this.addFile}
          onFileDialogCancel={this.onCancel}
          ref={dropzone => this.dropzone = dropzone}
        >
          {({ getRootProps, getInputProps, isDragActive }) => {
            return (
              <div {...getRootProps()} style={{ outline: 'none' }}
                className={classNames({ hide: maxNum === files.length })}
              >
                {
                  disableClick || <input {...getInputProps()} />
                }
                {content ? content :
                  < div className={classNames('wea-edc-drag-inner', { 'drag': isDragActive })}>
                    <div><Icon ecId={`${this && this.props && this.props.ecId || ''}_Icon@y96bql`} type='plus' /></div>
                    <div>{tip || getLabel('502257', '请选择或拖拽上传文件')}{`(${getLabel('505284', '最多$s个').replace('$s', maxNum)})${maxSize ? getLabel('505285', '限制每个$s以内').replace('$s', this.getSize(maxSize)) : ''}`}。{acceptTip && getLabel('506499', '仅支持') + acceptTip.replace(/,/g, '、')}</div>
                  </div>
                }
              </div>
            )
          }}
        </Dropzone>
      </div>
    )
  }
}